package com.yvon.maple.gateway.handler;


import com.yvon.boot.common.result.GlobalException;
import com.yvon.boot.common.result.ResponseData;
import com.yvon.boot.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.nio.file.AccessDeniedException;

import static com.yvon.boot.common.result.ResultCode.GLOBAL_EXCEPTION;
import static com.yvon.boot.common.result.ResultCode.RUNTIME_EXCEPTION;

/**
 * 全局异常处理程序
 *
 * @author : Yvon
 * @since : 2021-09-15
 */
@Slf4j
@ConditionalOnMissingBean(GlobalExceptionHandler.class)
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 数据校验异常处理.
     *
     * @param e the e
     * @return the response data
     * @author : Yvon / 2019-05-20
     */
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.OK)
    public ResponseData bindException(BindException e) {
        FieldError fieldError = e.getFieldError();
        log.warn("数据校验异常信息 ex={}", fieldError.getDefaultMessage(), e);
        return ResponseData.failed(ResultCode.INVALID_PARAMETER.getCode(), fieldError.getDefaultMessage());
    }



    /**
     * Illegal argument exception handler response data.
     *
     * @param e the e
     * @return the response data
     * @author : Yvon / 2020-05-18
     */
    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.OK)
    public ResponseData illegalArgumentExceptionHandler(IllegalArgumentException e) {
        log.warn("非法参数 ex={}", e.getMessage(), e);
        return ResponseData.failed(ResultCode.ILLEGAL_ARGUMENT.getCode(), e.getMessage());
    }


    /**
     * Access denied exception response data.
     *
     * @param e the e
     * @return the response data
     * @author : Yvon / 2020-06-22
     */
    @ExceptionHandler({AccessDeniedException.class})
    @ResponseStatus(HttpStatus.OK)
    public ResponseData accessDeniedException(AccessDeniedException e) {
        log.warn("拒绝访问 ex={}", e.getMessage(), e);
        return ResponseData.failed(HttpStatus.FORBIDDEN.value(), e.getMessage());
    }

    /**
     * 文件大小超出异常处理.
     *
     * @param e the e
     * @return the response data
     * @author : Yvon / 2020-05-25
     */
    @ExceptionHandler({MaxUploadSizeExceededException.class})
    @ResponseStatus(HttpStatus.OK)
    public ResponseData maxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        log.warn("文件大小超出最大限制", e);
        return ResponseData.failed(ResultCode.MAX_UPLOAD_SIZE_EXCEEDED);
    }




    /**
     * 运行时异常处理.
     *
     * @param e the e
     * @return R r
     * @author : Yvon / 2019-04-24
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.OK)
    public ResponseData runtimeException(RuntimeException e) {
        log.error("运行时异常信息 ex={}", e.getMessage(), e);
        return ResponseData.failed(RUNTIME_EXCEPTION);
    }


    /**
     * 自定义全局异常.
     *
     * @param e the e
     * @return the response data
     * @author : Yvon / 2020-05-25
     */
    @ExceptionHandler({GlobalException.class})
    @ResponseStatus(HttpStatus.OK)
    public ResponseData globalExceptionHandler(GlobalException e) {
        log.error("自定义全局异常 ex={}", e.getMessage(), e);
        return ResponseData.failed(e.getCode(), e.getMessage());
    }

    /**
     * 全局异常处理.
     *
     * @param e the e
     * @return R r
     * @author : Yvon / 2019-04-24
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public ResponseData exception(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return ResponseData.failed(GLOBAL_EXCEPTION);
    }

}
